home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_497 / leftymouse / leftymouse.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  13KB  |  455 lines

  1. /*
  2.  *  LeftyMouse.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.01   initial release
  13.  *  V1.02   recompiled with main.c V1.02
  14.  *  V1.03   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  15.  *  V1.04   some really minor changes
  16.  */
  17.  
  18. #define VERSION "V1.04"
  19.  
  20. /********************************************************************
  21.  *                             interfacing                          *
  22.  ********************************************************************/
  23.  
  24. /*
  25.  *  include files
  26.  */
  27.  
  28. #include <stdarg.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <devices/inputevent.h>
  32. #include <libraries/commodities.h>
  33.  
  34. #include <clib/alib_protos.h>
  35. #include <clib/commodities_protos.h>
  36. #include <pragmas/commodities_pragmas.h>
  37. #include <clib/dos_protos.h>
  38. #include <pragmas/dos_pragmas.h>
  39. #include <clib/exec_protos.h>
  40. #include <pragmas/exec_pragmas.h>
  41. #include <clib/intuition_protos.h>
  42. #include <pragmas/intuition_pragmas.h>
  43.  
  44. #ifdef DEBUG
  45. #define printf KPrintF
  46. #include <clib/dlib_protos.h>
  47. #endif
  48.  
  49. /*
  50.  *  prototypes
  51.  */
  52. long request(char *title, char *gadgets, char *text, ...);
  53. struct Library *myopenlibrary(char *name, unsigned long version);
  54. void __saveds leftymouse(register CxMsg *cxm);
  55. void processmessages(void);
  56.  
  57. /*
  58.  *  global data defined in other moduls
  59.  *
  60.  *  libraries opened by startup code; basepointers needed by function pragmas
  61.  */
  62. extern struct Library *DOSBase;
  63. extern struct Library *SysBase;
  64.  
  65. /*
  66.  *  Disable SAS/C CTRL/C handling
  67.  */
  68. void chkabort(void) {}
  69.  
  70. /********************************************************************
  71.  *                             global data                          *
  72.  ********************************************************************/
  73.  
  74. /*
  75.  *  definition of all messages (multi language support not completed yet)
  76.  */
  77. #ifdef GERMAN
  78.  
  79. #define RETRY_GADGETS           "Wiederholen|Abbrechen"
  80. #define RESUME_GADGETS          "Weiter"
  81. #define MSG_LIBRARY_OPENERR     "Die %s (V%ld+) kann nicht geöffnet werden!"
  82. #define COM_NAME                "LeftyMouse"
  83. #define COM_DESCR               "Vertauscht linke und rechte Maustaste"
  84.  
  85. #else
  86.  
  87. #define RETRY_GADGETS           "Retry|Cancel"
  88. #define RESUME_GADGETS          "Resume"
  89. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  90. #define COM_NAME                "LeftyMouse"
  91. #define COM_DESCR               "Swaps left and right mousebutton"
  92.  
  93. #endif
  94.  
  95. #define COM_TITLE           COM_NAME " " VERSION
  96. #define CX_PRIORITY         "CX_PRIORITY"
  97. #define DEF_CX_PRIORITY     0
  98.  
  99. /*
  100.  *  data for cback.o
  101.  */
  102. long _stack = 2048l;
  103. char *_procname = COM_NAME;
  104. long _priority = 0l;
  105. long _BackGroundIO = 1;
  106. extern BPTR _Backstdout;
  107.  
  108. /*
  109.  *  library base pointers
  110.  */
  111. struct Library *IntuitionBase;
  112. struct Library *CxBase;
  113. struct Library *IconBase;
  114.  
  115. /*
  116.  *  message port
  117.  */
  118. struct MsgPort *cxport = NULL;
  119.  
  120. /*
  121.  *  signal flag
  122.  */
  123. unsigned long cxsigflag = 0l;
  124.  
  125. /*
  126.  *  programtitle and version for Version command
  127.  */
  128. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  129.  
  130. /*
  131.  *  helpstring
  132.  */
  133. #ifdef GERMAN
  134. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  135.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<n>]\n";
  136. #else
  137. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  138.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<n>]\n";
  139. #endif
  140.  
  141. /*
  142.  *  the tooltypearray
  143.  */
  144. char **tooltypes;
  145.  
  146. /*
  147.  *  our broker
  148.  */
  149. CxObj *broker = NULL;
  150.  
  151. struct NewBroker newbroker = {
  152.     NB_VERSION,                         /* BYTE nb_Version               */
  153.     COM_NAME,                           /* BYTE *nb_Name                 */
  154.     COM_TITLE,                          /* BYTE *nb_Title                */
  155.     COM_DESCR,                          /* BYTE *nb_Descr                */
  156.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  157.     0,                                  /* SHORT nb_Flags                */
  158.     0,                                  /* BYTE nb_Pri                   */
  159.     NULL,                               /* struct MsgPort nb_Port        */
  160.     0                                   /* WORD nb_ReservedChannel       */
  161. };
  162.  
  163. /*
  164.  *  our input description string
  165.  */
  166. IX myix = {
  167.     IX_VERSION,                 /* UBYTE ix_version     */
  168.     IECLASS_RAWMOUSE,           /* UBYTE ix_Class       */
  169.     IECODE_LBUTTON,             /* UWORD ix_Code        */
  170.     0x007e,                     /* UWORD ix_CodeMask    */
  171.     0,                          /* UWORD ix_Qualifier   */
  172.     0,                          /* UWORD ix_Qualmask    */
  173.     0                           /* UWORD ix_QualSame    */
  174.     };
  175.  
  176. /********************************************************************
  177.  *                             functions                            *
  178.  ********************************************************************/
  179.  
  180. /*
  181.  *  request(): a glue routine to EasyRequest as simple as printf plus
  182.  *             titlestring, gadgettexts
  183.  *
  184.  *  Input: char *title:         pointer to the title of the requester
  185.  *         char *gadgets:       pointer to gadgettext
  186.  *         char *text:          text displayed in requester
  187.  *
  188.  *  Result: same as EasyrequestArgs()
  189.  *
  190.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  191.  */
  192. long request(char *title, char *gadgets, char *text, ...)
  193. {
  194.     /*
  195.      *  structure textreq only needed in this function, so hide it here
  196.      *  must be static, in order to be initialized only once
  197.      */
  198.     static struct EasyStruct textreq = {
  199.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  200.         0l,                         /* ULONG es_Flags           */
  201.         NULL,                       /* UBYTE *es_Title          */
  202.         NULL,                       /* UBYTE *es_TextFormat     */
  203.         NULL,                       /* UBYTE *es_GadgetFormat   */
  204.         };
  205.     va_list ap;
  206.     long rc;
  207.  
  208.     /*
  209.      *  get start of variable arguments
  210.      */
  211.     va_start(ap, text);
  212.  
  213.     /*
  214.      *  update textreq
  215.      */
  216.     textreq.es_Title = (UBYTE *)title;
  217.     textreq.es_TextFormat = (UBYTE *)text;
  218.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  219.  
  220.     /*
  221.      *  win may be NULL
  222.      */
  223.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  224.  
  225.     va_end(ap);
  226.  
  227.     return(rc);
  228. }
  229.  
  230. /*
  231.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  232.  *                   if OpenLibrary() fails, to give the user a chance to
  233.  *                   copy the library to libs: and retry
  234.  *                   requires request(), see above
  235.  */
  236. struct Library *myopenlibrary(char *name, unsigned long version)
  237. {
  238.     static char errortext[] = MSG_LIBRARY_OPENERR;
  239.     struct Library *libptr;
  240.     long ok = TRUE;
  241.  
  242.     do {
  243.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  244.             if (IntuitionBase) {
  245.                 ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  246.                 }
  247.             else ok = FALSE;
  248.             }
  249.         } while (!libptr && ok);
  250.  
  251.     #ifdef DEBUG
  252.     printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr);
  253.     #endif
  254.     return(libptr);
  255. }
  256.  
  257. void main(int argc, char *argv[])
  258. {
  259.     CxObj *filter;
  260.     CxObj *customobj;
  261.     struct Message *msg;
  262.  
  263.     if ((argc > 1) && (*argv[1] == '?')) {
  264.         /*
  265.          *  display help string
  266.          */
  267.         if (_Backstdout) {
  268.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  269.             Close(_Backstdout);
  270.             }
  271.         return;
  272.         }
  273.     else if (argc && _Backstdout) Close(_Backstdout);
  274.  
  275.     if (IntuitionBase = myopenlibrary("intuition.library", 37l)) {
  276.         /*
  277.          *  parse command line or tool types
  278.          *
  279.          *  we need icon.library therefore
  280.          */
  281.         if (IconBase = myopenlibrary("icon.library", 37l)) {
  282.  
  283.             /*
  284.              * create tooltypes array (requires icon.library open!!!)
  285.              */
  286.             tooltypes = (char **)ArgArrayInit(argc, argv);
  287.  
  288.             newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  289.  
  290.             ArgArrayDone();
  291.  
  292.             CloseLibrary(IconBase);
  293.  
  294.             if (CxBase = myopenlibrary("commodities.library", 37l)) {
  295.  
  296.                 /*
  297.                  *  create our message port
  298.                  */
  299.                 if (cxport = CreateMsgPort()) {
  300.  
  301.                     cxsigflag = 1l << cxport->mp_SigBit;
  302.                     newbroker.nb_Port = cxport;
  303.  
  304.                     if (broker = CxBroker(&newbroker, NULL)) {
  305.  
  306.                         if (filter = CxFilter(NULL)) {
  307.  
  308.                             SetFilterIX(filter, &myix);
  309.                             AttachCxObj(broker, filter);
  310.  
  311.                             if (customobj = CxCustom(leftymouse, 0l)) {
  312.  
  313.                                 AttachCxObj(filter, customobj);
  314.  
  315.                                 if (!CxObjError(filter)) {
  316.  
  317.                                     /*
  318.                                      *  activate our commodity
  319.                                      */
  320.                                     ActivateCxObj(broker, 1l);
  321.                                     /*
  322.                                      *  now watch our numerous ports
  323.                                      */
  324.                                     processmessages();
  325.  
  326.                                     } /* if !CxObjError() */
  327.  
  328.                                 } /* if customobj */
  329.  
  330.                             } /* if filter */
  331.  
  332.                         DeleteCxObjAll(broker);
  333.  
  334.                         } /* if broker */
  335.  
  336.                         #ifdef DEBUG
  337.                         else printf("main(): CxBroker() failed!\n");
  338.                         #endif
  339.  
  340.                     /*
  341.                      *  delete our message port after replying all pending messages
  342.                      */
  343.                     while (msg = GetMsg(cxport)) ReplyMsg(msg);
  344.                     DeleteMsgPort(cxport);
  345.                     } /* if cxport */
  346.  
  347.                     #ifdef DEBUG
  348.                     else printf("main(): CraeteMsgPort() failed!\n");
  349.                     #endif
  350.  
  351.                 CloseLibrary(CxBase);
  352.                 } /* if CxBase */
  353.  
  354.             } /* if IconBase */
  355.  
  356.         CloseLibrary(IntuitionBase);
  357.         } /* if IntuitionBase */
  358.  
  359. } /* main() */
  360.  
  361. void processmessages(void)
  362. {
  363.     struct Message *msg;
  364.     unsigned long msgid;
  365.     unsigned long msgtype;
  366.     unsigned long sigreceived;
  367.     unsigned short quit = FALSE;
  368.  
  369.     while (!quit) {
  370.  
  371.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
  372.  
  373.         #ifdef DEBUG
  374.         printf("processmessages(): signal received\n");
  375.         #endif
  376.  
  377.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  378.  
  379.         if (sigreceived & cxsigflag) {
  380.  
  381.             while (msg = (struct Message *)GetMsg(cxport)) {
  382.  
  383.                 msgid = CxMsgID((CxMsg *)msg);
  384.                 msgtype = CxMsgType((CxMsg *)msg);
  385.  
  386.                 ReplyMsg(msg);
  387.  
  388.                 switch (msgtype) {
  389.  
  390.                     case CXM_COMMAND:
  391.                         switch (msgid) {
  392.  
  393.                             case CXCMD_UNIQUE:
  394.                             case CXCMD_KILL:
  395.                                 quit = TRUE;
  396.                                 break;
  397.  
  398.                             case CXCMD_DISABLE:
  399.                                 ActivateCxObj(broker, 0l);
  400.                                 break;
  401.  
  402.                             case CXCMD_ENABLE:
  403.                                 ActivateCxObj(broker, 1l);
  404.                                 break;
  405.  
  406.                             }
  407.                         break;
  408.  
  409.                     } /* switch msgtype */
  410.  
  411.                 } /* while CxMsg */
  412.  
  413.             } /* if (sigreceived & cxsigflag) */
  414.  
  415.         } /* while !quit */
  416.  
  417.     ActivateCxObj(broker, 0l);
  418. }
  419.  
  420. void __saveds leftymouse(register CxMsg *cxm)
  421. {
  422.     register struct InputEvent *ie;
  423.  
  424.     /*
  425.      *  this function is called directly from somewhere,
  426.      *  so set up base register A4
  427.      */
  428.  
  429.     if (ie = (struct InputEvent *)CxMsgData(cxm)) {
  430.  
  431.         #ifdef DEBUG
  432.         printf("Class: %lx Code: %lx, Qualifier: %lx\n",
  433.                ie->ie_Class, ie->ie_Code, ie->ie_Qualifier);
  434.         #endif
  435.  
  436.         /*
  437.          *  IECODE_LBUTTON <-> IECODE_RBUTTON
  438.          *  IECODE_LBUTTON | IECODE_UP_PREFIX <-> IECODE_RBUTTON | IECODE_UP_PREFIX
  439.          */
  440.         ie->ie_Code ^= 0x0001;
  441.         /*
  442.          *  IEQUALIFIER_LEFTBUTTON | IEQUALIFIER_RELATIVEMOUSE <->
  443.          *  IEQUALIFIER_RBUTTON | IEQUALIFIER_RELATIVEMOUSE
  444.          */
  445.         if (ie->ie_Qualifier & 0x6000) ie->ie_Qualifier ^= 0x6000;
  446.  
  447.         #ifdef DEBUG
  448.         printf("Class: %lx Code: %lx, Qualifier: %lx\n",
  449.                ie->ie_Class, ie->ie_Code, ie->ie_Qualifier);
  450.         #endif
  451.  
  452.         }
  453.  
  454. }
  455.